package mysgoog.bot.algo;

import java.util.*;

import mysgoog.board.*;
import mysgoog.gtp.*;
import mysgoog.util.*;

public class BoardSearch
{
    private static Board board;
    private static final int MAXLEVEL = 3;

    private static void init(Board board)
    {
        BoardSearch.board = board;
    }

    private static LinkedList<Integer> hisMovs = new LinkedList<Integer>();

    private static HashSet<Integer> posMovs(Color color, Worm worm)
    {
        HashSet<Integer> res = new HashSet<Integer>();
        for (int pos : worm)
            for (int i : board.getAround(pos))
                if (board.isLegal(color, i))
                    res.add(i);
        for (int hm : hisMovs)
        {
            if (board.wormAt(hm) == null)
            {
                Lib.debug("NULL!");
                Lib.debug("hisMov: " + new Vertex(hm).toString());
            }
            for (int pos : board.wormAt(hm))
                for (int i : board.getAround(pos))
                    if (board.isLegal(color, i))
                        res.add(i);
        }
        return res;
    }
    public static ArrayList<Integer> attack(Board board, Color color, Worm worm)
    {
        init(board);
        ArrayList<Integer> res = new ArrayList<Integer>();
        if (worm.getLibs().size() == 1)
        {
            int pos = worm.getLibs().getOne();
            if (board.isLegal(color, pos))
            {
                res.add(pos);
                return res;
            }
        }
        if (worm.getLibs().size() > MAXLEVEL)
            return res;
        int wormPos = worm.getOne();
        for (int pos : posMovs(color, worm))
        {
            board.play(color, pos);
            hisMovs.addLast(pos);
            if (!defend(color.complement(), wormPos, 2))
                res.add(pos);
            board.undo();
            hisMovs.removeLast();
        }
        return res;
    }
    public static ArrayList<Integer> defend(Board board, Color color, Worm worm)
    {
        init(board);
        ArrayList<Integer> res = new ArrayList<Integer>();
        if (worm.getLibs().size() > MAXLEVEL)
            return res;
        int wormPos = worm.getOne();
        for (int pos : posMovs(color, worm))
        {
            board.play(color, pos);
            hisMovs.addLast(pos);
            if (!attack(color.complement(), wormPos, 1))
                res.add(pos);
            board.undo();
            hisMovs.removeLast();
        }
        return res;
    }
    private static boolean attack(Color color, int wormPos, int level)
    {
        Worm worm = board.wormAt(wormPos);
        if (worm.getLibs().size() == 1)
        {
            int pos = worm.getLibs().getOne();
            if (board.isLegal(color, pos))
                return true;
        }
        if (level == MAXLEVEL)
            return false;
        if (MAXLEVEL - level + 1 < worm.getLibs().size())
            return false;
        for (int pos : posMovs(color, worm))
        {
            board.play(color, pos);
            hisMovs.add(pos);
            if (!defend(color.complement(), wormPos, level + 1))
            {
                board.undo();
                hisMovs.removeLast();
                return true;
            }
            board.undo();
            hisMovs.removeLast();
        }
        return false;
    }
    private static boolean defend(Color color, int wormPos, int level)
    {
        Worm worm = board.wormAt(wormPos);
        if (worm.getLibs().size() > MAXLEVEL - level + 1)
            return true;
        for (int pos : posMovs(color, worm))
        {
            board.play(color, pos);
            hisMovs.add(pos);
            if (!attack(color.complement(), wormPos, level))
            {
                board.undo();
                hisMovs.removeLast();
                return true;
            }
            board.undo();
            hisMovs.removeLast();
        }
        return false;
    }
}
